/*kZime*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <algorithm>

using namespace std;
/*-----------------------------------------------------------------------------*/
inline void File_Read() {
#ifndef MYLAB
	freopen("install.in", "r", stdin);
	freopen("install.out", "w", stdout);
#else
//	freopen("in.txt", "r", stdin);
#endif
}

int n, m, w[233], v[233], need[233], ref[233], cnt, head[233];
bool vis[233], instk[233];
int stk[233], top, tot;//tot is the num of the edges
int f[233][233 * 5];
class edge {
public:
	int to, ne;
	edge(){}
	edge(int to_, int ne_) {
		to = to_;
		ne = ne_;
	}
}e[233];

void addedge(int fr, int to) {
	e[++tot] = edge(to, head[fr]), head[fr] = tot;
}

inline int get_num() {
	int k = 0, f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar())if(c == '-') f = -1;
	for(; isdigit(c); c = getchar()) k = k * 10 + c - '0';
	return k * f;
}

inline void read() {
	n = get_num();
	m = get_num();
	for(int i = 1; i <= n; i++) {
		w[i] = get_num();
	}
	for(int i = 1; i <= n; i++) {
		v[i] = get_num();
	}
	for(int i = 1; i <= n; i++) {
		need[i] = get_num();
	}
}

inline void get_node() {
	for(int i = 1; i <= n; i++) {
		ref[i] = i;
	}//ref[i] is the softwere[i] --> the node on the dp tree
	cnt = n;
	int tmp, now;
	for(int i = 1; i <= n; i++) {
		if(vis[i]) continue;
		now = i;
		bool is_loop = false;
		do {
			if(vis[now]) {
				if(instk[now]) is_loop = true;
				break;
			}
			vis[now] = true;
			instk[now] = true;
			stk[++top] = now;
			now = need[now];
		} while(true);
		if(is_loop) {
			cnt++;
			do {
				tmp = stk[top--];
				instk[tmp] = false;
				ref[tmp] = cnt;
				w[cnt] += w[tmp];
				v[cnt] += v[tmp];
				if(tmp == now) break;
			} while(top);
		}
		while(top) {
			tmp = stk[top--];
			instk[tmp] = false;
		}
	}
}

void dp(int now, int rem) {
	for(int i = head[now]; i; i = e[i].ne) {
		int to = e[i].to;
		for(int j = 0; j <= rem; j++) f[to][j] = f[now][j];
		dp(to, rem - w[now]);
		for(int j = w[to]; j <= rem; j++) f[now][j] = max(f[now][j], f[to][j - w[to]] + v[to]);
	}
}

inline void solve() {
	get_node();
	for(int i = 1; i <= n; i++) {
		if(ref[i] == ref[need[i]])continue;
		addedge(ref[need[i]], ref[i]);
	}
	for(int i = n + 1; i <= cnt; i++) {
		addedge(0, i);
	}
	dp(0, m);
	printf("%d", f[0][m]);
}

int main() {
	File_Read();
	read();
	solve();
	return 0;
}
